package gang.org.springframework.framework.bean;

import gang.org.springframework.framework.factory.GangConstructorArgumentValues;
import gang.org.springframework.framework.factory.config.GangAutowireCapableBeanFactory;
import gang.org.springframework.framework.io.GangResource;
import gang.org.springframework.framework.support.GangMethodOverrides;
import gang.org.springframework.framework.util.GangClassUtils;

/**
 * @author gang.chen
 * @Date 2021/6/14 20:36
 */
public abstract class GangAbstractBeanDefinition extends GangBeanMetadataAttributeAccessor implements GangBeanDefinition{

    private int role = GangBeanDefinition.ROLE_INFRASTRUCTURE;

    public static final String SCOPE_DEFAULT = "";

    private volatile Object beanClass;

    private String scope = SCOPE_DEFAULT;

    private boolean abstractFlag = false;

    private GangResource resource;

    private boolean lenientConstructorResolution = true;

    private String factoryBeanName;

    private String factoryMethodName;

    private GangMethodOverrides methodOverrides = new GangMethodOverrides();

    public GangConstructorArgumentValues constructorArgumentValues;

    public static final int autowire_no = GangAutowireCapableBeanFactory.autowire_no;

    public int autowireMode = autowire_no;

    public static final int autowire_autodetect = GangAutowireCapableBeanFactory.audowire_autodetect;


    private boolean synthetic = false;


    protected GangAbstractBeanDefinition()
    {

    }

    public abstract GangAbstractBeanDefinition cloneBeanDefinition();

    /**
     * @param original is instance of {@link GangRootBeanDefinition}
     * */
    protected GangAbstractBeanDefinition (GangBeanDefinition original){
        setBeanClassName(original.getBeanClassName());
        //该两类属性，以接口接到BeanDefinition使用
        setFactoryBeanName(original.getFactoryBeanName());
        setFactoryMethodName(original.getFactoryMethodName());
        if (original instanceof GangAbstractBeanDefinition){
            GangAbstractBeanDefinition originalAbd = (GangAbstractBeanDefinition) original;
            if(originalAbd.hasBeanClass()){
                setBeanClass(originalAbd.getBeanClass());
            }
        }
    }

    @Override
    public void setRole(int role) {
        this.role = role;
    }

    @Override
    public String getScope() {
        return this.scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public void setBeanClass(Object beanClass) {
        this.beanClass = beanClass;
    }

    public Class<?> getBeanClass() {
        Object beanClassObject = this.beanClass;
        return (Class<?>)beanClassObject;
    }

    public boolean hasBeanClass(){
        return (this.beanClass instanceof Class);
    }

    @Override
    public boolean isSingleton() {
        //return SCOPE_SINGLETON.equals(scope);
        return true;
    }

    @Override
    public String getBeanClassName() {
        /*
         * 业务意义
         * 1）beanClass 如果是封装主启动类，beanClass为Class
         * 2）beanClass 如果是自动装配类，beanClass为String
         * */
        Object beanClassObject = this.beanClass;
        if(beanClassObject instanceof Class){
            return ((Class<?>)beanClassObject).getName();
        }else{
            return (String) beanClassObject;
        }

    }

    @Override
    public void setBeanClassName(String beanClassName) {
        this.beanClass = beanClassName;
    }

    public Class<?> resolveBeanClass(ClassLoader classLoader){
        String className = getBeanClassName();
        if (className == null) {
            return null;
        }

        Class<?> resolvedClass = GangClassUtils.forName(className,classLoader);
        this.beanClass = resolvedClass;
        return resolvedClass;
    }

    public void setResource(GangResource resource) {
        this.resource = resource;
    }

    public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
        this.lenientConstructorResolution = lenientConstructorResolution;
    }

    @Override
    public void setFactoryBeanName(String factoryBeanName) {
        this.factoryBeanName = factoryBeanName;
    }

    public void setFactoryMethodName(String factoryMethodName) {
        this.factoryMethodName = factoryMethodName;
    }

    @Override
    public String getFactoryBeanName() {
        return this.factoryBeanName;
    }

    @Override
    public String getFactoryMethodName() {
        return this.factoryMethodName;
    }

    @Override
    public boolean hasConstructorArgumentValues() {
        return false;
    }

    @Override
    public boolean isAbstract() {
        return false;
    }

    @Override
    public boolean isLazyInit() {
        return false;
    }

    public void setAbstract(boolean abstractFlag){
        this.abstractFlag = abstractFlag;
    }

    public boolean hasMethodOverrides(){
        return !this.methodOverrides.isEmpty();
    }

    public int getResolvedAutowireMode(){
        if (this.autowireMode == autowire_autodetect) {
            //TOTO
        }
        return this.autowireMode;
    }

    @Override
    public GangConstructorArgumentValues getConstructorArgumentValues() {

        if (this.constructorArgumentValues == null) {
            this.constructorArgumentValues = new GangConstructorArgumentValues();
        }
        return constructorArgumentValues;
    }

    public boolean isSynthetic() {
        return synthetic;
    }


}
